"""
通用工具管理器基类
提供标准化的工具管理功能，包括数据库操作、配置管理等
"""

from abc import ABC, abstractmethod
from typing import List, Dict, Any, Optional

from sqlalchemy.orm import Session

from pojo.ai_web_detail_tools_model import AIWebDetailToolsModel
from pojo.ai_web_tools_model import AIWebToolsModel


class ToolManager(ABC):
    """工具管理器基类"""

    @property
    @abstractmethod
    def category_name(self) -> str:
        """工具类别名称（必须由子类实现）"""
        pass

    @property
    @abstractmethod
    def category_code(self) -> str:
        """工具类别代码（必须由子类实现）"""
        pass

    @property
    @abstractmethod
    def category_description(self) -> str:
        """工具类别描述（必须由子类实现）"""
        pass

    @abstractmethod
    def get_tool_configs(self) -> List[Dict[str, Any]]:
        """获取工具配置列表（必须由子类实现）"""
        pass

    @abstractmethod
    def get_langchain_tool(self):
        """获取LangChain工具实例（必须由子类实现）"""
        pass

    def save_to_database(self, db_session: Session) -> Optional[AIWebToolsModel]:
        """
        保存工具配置到数据库（防重复保存）
        现在保存到两个表：ai_web_tools 和 ai_web_detail_tools
        """
        try:
            # 检查工具集是否已存在（优先使用category_code进行查询）
            existing_tools = db_session.query(AIWebToolsModel).filter(
                AIWebToolsModel.category_code == self.category_code
            ).first()

            if existing_tools:
                print(f"工具集 '{self.category_name}' (代码: {self.category_code}) 已存在，检查工具详情...")
                # 工具集存在，检查是否需要更新工具详情
                self._update_detail_tools(db_session, existing_tools.id)
                return existing_tools

            # 创建新的工具集
            tools_model = AIWebToolsModel(
                category_name=self.category_name,
                category_code=self.category_code,
                description=self.category_description,
                is_enabled=1
            )

            # 保存工具集到数据库
            db_session.add(tools_model)
            db_session.flush()  # 获取ID但不提交事务

            # 保存工具详情
            self._save_detail_tools(db_session, tools_model.id)

            # 提交事务
            db_session.commit()

            print(f"工具集 '{self.category_name}' (代码: {self.category_code}) 成功保存到数据库")
            return tools_model

        except Exception as e:
            print(f"保存工具集 '{self.category_name}' (代码: {self.category_code}) 到数据库失败: {e}")
            db_session.rollback()
            return None

    def _save_detail_tools(self, db_session: Session, parent_id: int) -> None:
        """保存工具详情到ai_web_detail_tools表"""
        try:
            tool_configs = self.get_tool_configs()

            for tool_config in tool_configs:
                # 检查该工具是否已存在
                existing_detail = db_session.query(AIWebDetailToolsModel).filter(
                    AIWebDetailToolsModel.parent_id == parent_id,
                    AIWebDetailToolsModel.tool_name == tool_config.get('tool_name'),
                    AIWebDetailToolsModel.tool_type == 1  # 基础工具
                ).first()

                if existing_detail:
                    print(f"基础工具 '{tool_config.get('tool_name')}' 已存在，跳过...")
                    continue

                # 创建新的工具详情记录
                detail_tool = AIWebDetailToolsModel(
                    parent_id=parent_id,
                    tool_type=1,  # 基础工具
                    tool_name=tool_config.get('tool_name', ''),
                    server_code=self.category_code,  # 基础工具使用category_code作为server_code
                    description=tool_config.get('description', ''),
                    is_enabled=tool_config.get('is_enabled', True),
                    parameters=tool_config.get('parameters', [])
                )

                db_session.add(detail_tool)
                print(f"添加基础工具: {tool_config.get('tool_name')} (服务代码: {self.category_code})")

            print(f"保存了 {len(tool_configs)} 个基础工具详情")

        except Exception as e:
            print(f"保存基础工具详情失败: {e}")
            raise

    def _update_detail_tools(self, db_session: Session, parent_id: int) -> None:
        """更新基础工具详情（如果需要）"""
        try:
            tool_configs = self.get_tool_configs()

            # 获取当前数据库中的基础工具详情
            existing_tools = db_session.query(AIWebDetailToolsModel).filter(
                AIWebDetailToolsModel.parent_id == parent_id,
                AIWebDetailToolsModel.tool_type == 1  # 基础工具
            ).all()

            existing_tool_names = {tool.tool_name for tool in existing_tools}
            config_tool_names = {config.get('tool_name') for config in tool_configs}

            # 添加新的基础工具
            new_tools = config_tool_names - existing_tool_names
            if new_tools:
                for tool_config in tool_configs:
                    if tool_config.get('tool_name') in new_tools:
                        detail_tool = AIWebDetailToolsModel(
                            parent_id=parent_id,
                            tool_type=1,  # 基础工具
                            tool_name=tool_config.get('tool_name', ''),
                            server_code=self.category_code,  # 基础工具使用category_code作为server_code
                            description=tool_config.get('description', ''),
                            is_enabled=tool_config.get('is_enabled', True),
                            parameters=tool_config.get('parameters', [])
                        )
                        db_session.add(detail_tool)
                        print(f"添加新的基础工具: {tool_config.get('tool_name')} (服务代码: {self.category_code})")

                # 更新现有工具的server_code（如果为空）
                for existing_tool in existing_tools:
                    if not existing_tool.server_code:
                        existing_tool.server_code = self.category_code
                        print(f"更新基础工具 '{existing_tool.tool_name}' 的服务代码为: {self.category_code}")

                db_session.commit()
                print(f"添加了 {len(new_tools)} 个新的基础工具")

        except Exception as e:
            print(f"更新基础工具详情失败: {e}")
            db_session.rollback()

    def initialize(self, db_session: Session) -> bool:
        """初始化工具到数据库"""
        result = self.save_to_database(db_session)
        return result is not None

    def get_tools_from_database(self, db_session: Session) -> List[Dict[str, Any]]:
        """从数据库获取基础工具详情列表"""
        try:
            # 查找工具集
            tools_model = db_session.query(AIWebToolsModel).filter(
                AIWebToolsModel.category_code == self.category_code
            ).first()

            if not tools_model:
                return []

            # 查找基础工具详情（tool_type=1）
            detail_tools = db_session.query(AIWebDetailToolsModel).filter(
                AIWebDetailToolsModel.parent_id == tools_model.id,
                AIWebDetailToolsModel.tool_type == 1
            ).all()

            return [tool.to_dict() for tool in detail_tools]

        except Exception as e:
            print(f"从数据库获取基础工具详情失败: {e}")
            return []

    def get_enabled_tools_from_database(self, db_session: Session) -> List[Dict[str, Any]]:
        """从数据库获取启用的基础工具详情列表"""
        try:
            # 查找工具集
            tools_model = db_session.query(AIWebToolsModel).filter(
                AIWebToolsModel.category_code == self.category_code
            ).first()

            if not tools_model:
                return []

            # 查找启用的基础工具详情（tool_type=1）
            detail_tools = db_session.query(AIWebDetailToolsModel).filter(
                AIWebDetailToolsModel.parent_id == tools_model.id,
                AIWebDetailToolsModel.tool_type == 1,
                AIWebDetailToolsModel.is_enabled == True
            ).all()

            return [tool.to_dict() for tool in detail_tools]

        except Exception as e:
            print(f"从数据库获取启用的基础工具详情失败: {e}")
            return []

    def update_tool_status(self, db_session: Session, tool_name: str, is_enabled: bool) -> bool:
        """更新基础工具状态"""
        try:
            # 查找工具集
            tools_model = db_session.query(AIWebToolsModel).filter(
                AIWebToolsModel.category_code == self.category_code
            ).first()

            if not tools_model:
                print(f"未找到工具集: {self.category_code}")
                return False

            # 查找基础工具详情
            detail_tool = db_session.query(AIWebDetailToolsModel).filter(
                AIWebDetailToolsModel.parent_id == tools_model.id,
                AIWebDetailToolsModel.tool_type == 1,
                AIWebDetailToolsModel.tool_name == tool_name
            ).first()

            if not detail_tool:
                print(f"未找到基础工具: {tool_name}")
                return False

            # 更新状态
            detail_tool.is_enabled = is_enabled
            db_session.commit()

            print(f"基础工具 '{tool_name}' 状态更新为: {'启用' if is_enabled else '禁用'}")
            return True

        except Exception as e:
            print(f"更新基础工具状态失败: {e}")
            db_session.rollback()
            return False

    def get_tool_statistics(self, db_session: Session) -> Dict[str, int]:
        """获取基础工具统计信息"""
        try:
            # 查找工具集
            tools_model = db_session.query(AIWebToolsModel).filter(
                AIWebToolsModel.category_code == self.category_code
            ).first()

            if not tools_model:
                return {"total": 0, "enabled": 0, "disabled": 0}

            # 统计基础工具详情
            total_count = db_session.query(AIWebDetailToolsModel).filter(
                AIWebDetailToolsModel.parent_id == tools_model.id,
                AIWebDetailToolsModel.tool_type == 1
            ).count()

            enabled_count = db_session.query(AIWebDetailToolsModel).filter(
                AIWebDetailToolsModel.parent_id == tools_model.id,
                AIWebDetailToolsModel.tool_type == 1,
                AIWebDetailToolsModel.is_enabled == True
            ).count()

            disabled_count = total_count - enabled_count

            return {
                "total": total_count,
                "enabled": enabled_count,
                "disabled": disabled_count
            }

        except Exception as e:
            print(f"获取基础工具统计信息失败: {e}")
            return {"total": 0, "enabled": 0, "disabled": 0}


class SingleToolConfig:
    """单个工具配置的辅助类"""

    def __init__(self, tool_id: int, tool_name: str, description: str,
                 is_enabled: bool = True):
        self.tool_id = tool_id
        self.tool_name = tool_name
        self.description = description
        self.is_enabled = is_enabled
        self.parameters = []

    def add_parameter(self, param_name: str, param_type: str, description: str,
                      default_value: Any = None, is_required: bool = False):
        """添加参数"""
        self.parameters.append({
            "param_name": param_name,
            "param_type": param_type,
            "description": description,
            "default_value": default_value,
            "is_required": is_required
        })

    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "id": self.tool_id,
            "tool_name": self.tool_name,
            "description": self.description,
            "is_enabled": self.is_enabled,
            "parameters": self.parameters
        }
